import pandas as pd
from typing import List, Tuple, Dict, Optional
import json

# Excel 文件配置
EXCEL_FILES = [
    "E22H-R CAN communication Matrix_MMI(AVM)-0117节点--系统设置和放电-45个can信号_0117.xlsx",
    "E22H-R CAN communication Matrix_MMI(AVM)-充电状态相关20个can信号.xlsx",
    "E22H-R CAN communication Matrix_MMI(AVM)-行程统计和超级续航-26个can信号.xlsx"
]
SHEET_NAME = 'Information_CAN_Message_Detail'
COLUMN_MAPPING = {
    'signal_name': 'SignalName\n信号名称',
    'default_value': 'Default value(Physical)\n默认值',
    'message_id': 'Msg ID(Hex)\n消息标识符',
    'message_name': 'Message Name\n消息名称',
    'ecp_id': 'ECP ID',
    'pro_id': 'PRO_ID'
}


def read_excel_data(file_path: str = 'input.xlsx', sheet_name: str = SHEET_NAME) -> pd.DataFrame:
    """读取 Excel 文件数据"""
    return pd.read_excel(file_path, sheet_name=sheet_name)


def read_signals_file(file_path: str = 'signals.txt') -> List[str]:
    """读取信号文件并返回信号列表"""
    with open(file_path, 'r') as file:
        return [line.strip() for line in file if line.strip()]


def find_message_info(df: pd.DataFrame, row_index: int, message_id_col: str, message_name_col: str) -> Tuple[str, str]:
    """向上查找消息 ID 和消息名称"""
    for i in range(row_index, -1, -1):
        row = df.iloc[i]
        message_id = row[message_id_col]
        message_name = row[message_name_col]
        if pd.notna(message_id):
            return str(message_id), str(message_name)
    return "", ""


def extract_ecp_and_pro_id(df: pd.DataFrame, signal: str) -> Tuple[str, str]:
    """从 DataFrame 中提取 ECP ID 和 PRO ID"""
    matched_rows = df[df[COLUMN_MAPPING['signal_name']].str.strip() == signal]
    if not matched_rows.empty and pd.notna(matched_rows.iloc[0][COLUMN_MAPPING['ecp_id']]):
        return (
            str(matched_rows.iloc[0][COLUMN_MAPPING['ecp_id']]),
            str(matched_rows.iloc[0][COLUMN_MAPPING['pro_id']])
        )
    return "", ""


def find_ecp_id_and_prop_id(signal: str) -> Tuple[str, str]:
    """从多个 Excel 文件中查找信号的 ECP ID 和 PRO ID"""
    for excel_file in EXCEL_FILES:
        df = read_excel_data(excel_file)
        ecp_id, pro_id = extract_ecp_and_pro_id(df, signal)
        if ecp_id:
            return ecp_id, pro_id
    return "", ""


def process_signal(df: pd.DataFrame, signal: str, ecpidMap):
    """处理单个信号并返回结果字典"""
    matched_rows = df[df[COLUMN_MAPPING['signal_name']].str.strip() == signal]
    if matched_rows.empty:
        return None

    default_value = matched_rows.iloc[0][COLUMN_MAPPING['default_value']]
    row_index = matched_rows.index[0]
    message_id, message_name = find_message_info(
        df, row_index, COLUMN_MAPPING['message_id'], COLUMN_MAPPING['message_name']
    )
    ecp_id, pro_id = find_ecp_id_and_prop_id(signal)

    ecp_id_name = ""

    if ecpidMap.get(ecp_id) is not None:
        ecp_id_name = ecpidMap[ecp_id]

    return {
        "signalName": signal,
        "messageId": message_id,
        "messageName": message_name,
        "defaultValue": default_value,
        "ecpIDName": ecp_id_name,
        "ecpIDValue": ecp_id,
        "proId": pro_id
    }


def process_signals(df: pd.DataFrame, signals: List[str], ecpidMap):
    """处理信号列表并返回结果"""
    result = []
    for signal in signals:
        signal_result = process_signal(df, signal, ecpidMap)
        if signal_result is not None:
            result.append(signal_result)
    return result


def getEcpIdMap():
    ecpid_file_path = "ECP_Includes_ext.h"
    ecpidArray = read_signals_file(ecpid_file_path)
    ecpidMap = parse_ecp_id(ecpidArray)
    return ecpidMap


def parse_ecp_id(lines):
    result = {}
    for line in lines:
        line = line.split('#', 1)[0].split('//', 1)[0].strip()

        if '=' not in line:
            continue

        key, value = map(str.strip, line.split('=', 1))
        value = value.rstrip(',')
        result[value] = key

    return result


def write_json(result, fileName):
    with open(fileName, 'w', encoding='utf-8') as json_file:
        json.dump(result, json_file, ensure_ascii=False, indent=4)


def main():
    """主函数：读取数据，处理信号并输出结果"""
    # 读取数据
    df = read_excel_data()
    print("Excel 文件的列名：", df.columns.tolist())

    # 读取信号
    signals = read_signals_file()

    ecpidMap = getEcpIdMap()

    # 处理信号数据
    result = process_signals(df, signals, ecpidMap)

    # 输出结果
    print(result)

    write_json(result, "xxx.json")


if __name__ == "__main__":
    main()
